package com.asiainfo.integration.utils;

import com.asiainfo.integration.queue.QueueDetails;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * Usage:
 *
 * @author Charkey
 * @date 4/1/2016
 */
public class ConfigProvider {

    private static final Logger LOGGER = LoggerFactory.getLogger(ConfigProvider.class);

    private static Map<String, QueueDetails> queueDetailsMap = new TreeMap<String, QueueDetails>();

    private static Map<String, String> serverIpsMap = new HashMap<String, String>();

    public static void initialize() {
        LOGGER.info("initialing queue details map");
        loadQueueDetails(queueDetailsMap);
        LOGGER.info("queue details map initialed");
        LOGGER.info("initialing servers map");
        loadServers(serverIpsMap);
        LOGGER.info("servers map initialed");
    }

    public static void reInitialize() {
        LOGGER.info("reInitialing queue details map");
        clear();
        initialize();
        LOGGER.info("queue details map reInitialed");
    }

    public static void clear() {
        queueDetailsMap.clear();
    }

    private static void loadQueueDetails(Map queueDetailsMap) {
        loadQueueDetailsFromFile(queueDetailsMap);
    }

    private static void loadServers(Map serverIpsMap) {
        loadServersFromFile(serverIpsMap);
    }

    private static void loadQueueDetailsFromFile(Map queueDetailsMap) {
        try {
            URL url = ConfigProvider.class.getClassLoader().getResource("config/queue/queue-details.xml");
            SAXReader reader = new SAXReader();
            InputStream in = new FileInputStream(new File(url.toURI().getPath()));
            Document document = reader.read(in);

            Element root = document.getRootElement();
            List<Element> elements = root.elements();
            for (Element element : elements) {
                QueueDetails queueDetails = new QueueDetails();
                queueDetails.xmlElementToAttribute(element);
                queueDetailsMap.put(element.element("interfaceName").getText(), queueDetails);
            }
        } catch (DocumentException e) {
            e.printStackTrace();
            LOGGER.error("DocumentException", e);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            LOGGER.error("FileNotFoundException", e);
        } catch (URISyntaxException e) {
            e.printStackTrace();
            LOGGER.error("URISyntaxException", e);
        }
    }

    private static void loadServersFromFile(Map serverIpsMap) {
        try {
            URL url = ConfigProvider.class.getClassLoader().getResource("config/properties.xml");
            SAXReader reader = new SAXReader();
            InputStream in = new FileInputStream(new File(url.toURI().getPath()));
            Document document = reader.read(in);

            Element root = document.getRootElement();
            Element serversElement = root.element("servers");
            List<Element> servers = serversElement.elements();
            for (Element element : servers) {
                String env = element.element("env").getText();
                String ip = element.element("ip").getText();
                serverIpsMap.put(env, ip);
                serverIpsMap.put(ip, env);
            }
        } catch (DocumentException e) {
            e.printStackTrace();
            LOGGER.error("DocumentException", e);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            LOGGER.error("FileNotFoundException", e);
        } catch (URISyntaxException e) {
            e.printStackTrace();
            LOGGER.error("URISyntaxException", e);
        }
    }

    public static Map<String, QueueDetails> getQueueDetailsMap() {
        return queueDetailsMap;
    }

    public static void setQueueDetailsMap(Map<String, QueueDetails> queueDetailsMap) {
        ConfigProvider.queueDetailsMap = queueDetailsMap;
    }

    public static Map<String, String> getServerIpsMap() {
        return serverIpsMap;
    }

    public static void setServerIpsMap(Map<String, String> serverIpsMap) {
        ConfigProvider.serverIpsMap = serverIpsMap;
    }
}
